import { ref, nextTick, onMounted, onUnmounted, onActivated, onDeactivated } from 'vue'

export function useSticky(parent, canFixed) {
  const tablexy = ref({}) //表格的左边宽度信息
  const fixedRightDom = ref(null) //右侧
  const fixedLeftDom = ref(null) //左侧栏固定
  const scrollDom = ref(null) //滚动的dom
  const parentDom = ref(null) //表格的父元素dom
  const paginationDom = ref(null)
  const tableWidth = ref(0)
  const timerList = ref([])
  const tableDom = ref(null)
  const headerWidth = ref(null)
  const containerDom = document.getElementsByClassName('main-box')

  onMounted(() => {
    clearListener()
    let timer = setTimeout(() => {
      initFixedHeader()
      clearTimeout(timer)
    }, 300)
    window.addEventListener('resize', resizeChange)
  })
  onUnmounted(() => {
    clearListener()
  })
  onActivated(() => {
    initFixedHeader()
    updateFixedRight()
    window.addEventListener('resize', resizeChange)
    let timer
    timer = setTimeout(() => {
      let container = containerDom
      if (container[0].scrollTop > 0) {
        container[0].scrollTop = container[0].scrollTop + 2
      }
      clearTimeout(timer)
    }, 1000)
  })
  onDeactivated(() => {
    clearListener()
  })
  const rafThrottle = (fn) => {
    let locked = false
    return function(...args) {
      if (locked) return
      locked = true
      window.requestAnimationFrame((_) => {
        fn.apply(this, args)
        locked = false
      })
    }
  }
  // 拖拽改变表头宽度，更新表格宽度，或有表格改动时导致的样式错乱使用
  const headerDragend = async () => {
    await updateWidth()
    await updateFixedRight()
    // setScrollXWidth()
  }
  // 窗口大小变化时，初始化
  const resizeChange = () => {
    headerDragend()
    let timer = setTimeout(() => {
      initFixedHeader()
      clearTimeout(timer)
    }, 300)
  }
  const initFixedHeader = async () => {
    if (parent && canFixed) {
      parentDom.value = document.getElementsByClassName(parent)
      if (parentDom.value && parentDom.value.length !== 0) {
        if (parentDom.value[0].querySelector('.el-table__header-wrapper')) {
          tableWidth.value = parentDom.value[0].querySelector('.el-table__header-wrapper').getBoundingClientRect().width
        }
        setScrollXWidth()
        tableDom.value = parentDom.value[0].getElementsByClassName('el-table__header-wrapper')
        scrollDom.value = document.querySelector('.main-box')
        scrollDom.value.addEventListener('scroll', scrollEvent)
      }
    }
  }
  // 清空sticky监听事件，页面卸载等情况使用
  const clearListener = () => {
    if (scrollDom.value) {
      scrollDom.value.removeEventListener('scroll', scrollEvent)
      window.removeEventListener('resize', resizeChange)
      clearFixedStyle()
      timerList.value.forEach((key) => {
        clearTimeout(key)
      })
    }
  }
  // 更新右侧固定栏
  const updateFixedRight = () => {
    let { fixedRightHeaderDom, dom } = getFixedDom()
    if (dom.classList.contains('fixed')) {
      let timer = setTimeout(() => {
        setFixedStyle({
          dom: fixedRightHeaderDom,
          left: fixedRightDom.value[0] ? fixedRightDom.value[0].getBoundingClientRect().left + 'px' : '',
          width: fixedRightDom.value[0] ? getComputedStyle(fixedRightDom.value[0]).width : '',
          scrollLeft: fixedRightHeaderDom ? fixedRightHeaderDom.scrollWidth : ''
        })
        clearTimeout(timer)
      }, 100)
    }
  }
  // 用于更新tableWidth，headerWidth，制作虚拟滚动条
  const setScrollXWidth = () => {
    let timer = setTimeout(() => {
      if (!parentDom.value) parentDom.value = document.getElementsByClassName(parent)
      if (parentDom.value.length == 0) return
      let dom = parentDom.value[0].querySelector('.el-table__header')
      tableWidth.value = parentDom.value[0].querySelector('.el-table__body-wrapper').getBoundingClientRect().width
      tableDom.value[0].style.width = tableWidth.value + 'px'
      updateHeaderHeight()
      headerWidth.value = dom.style.width
      clearTimeout(timer)
    }, 200)
  }
  // 更新表格宽度，（拖拽改变宽度时使用）
  const updateWidth = () => {
    if (!parentDom.value) parentDom.value = document.getElementsByClassName(parent)
    const bodyWrapperDom = parentDom.value[0].getElementsByClassName('el-table__body-wrapper')[0]
    const width = getComputedStyle(bodyWrapperDom).width //表格宽度
    // 给表格设置宽度。
    const tableParent = tableDom.value
    for (let i = 0; i < tableParent.length; i++) {
      tableParent[i].style.width = width
    }
  }
  const getFixedDom = () => {
    let fixedRightHeaderDom, fixedRightBox, fixedLeftHeaderDom, fixedLeftBox
    let dom = tableDom.value[0]
    if (fixedLeftDom.value && fixedLeftDom.value[0]) {
      let lefarr = fixedLeftDom.value[0].children
      fixedLeftHeaderDom = lefarr[0]
      fixedLeftBox = lefarr[1]
    }
    if (fixedRightDom.value && fixedRightDom.value[0]) {
      let rightarr = fixedRightDom.value[0].children
      fixedRightHeaderDom = rightarr[0]
      fixedRightBox = rightarr[1]
    }
    return { fixedRightHeaderDom, fixedRightBox, fixedLeftHeaderDom, fixedLeftBox, dom }
  }
  // 更新表头高度，表头高度有可能改变
  const updateHeaderHeight = () => {
    nextTick(() => {
      tableDom.value = parentDom.value[0].getElementsByClassName('el-table__header-wrapper')
      let obj = tableDom.value[0].getBoundingClientRect()
      if (obj.height != tablexy.value.height) {
        tablexy.value.height = obj.height
        let { dom } = getFixedDom()
        if (dom.classList.contains('fixed')) {
          let timer = setTimeout(() => {
            parentDom.value[0].getElementsByClassName('el-table__fixed-body-wrapper')[0].style.top = 0
            let container = containerDom
            if (container && container[0]) {
              container[0].scrollTop = container[0].scrollTop + 3
            }
            clearTimeout(timer)
          }, 100)
        }
      }
    })
  }
  // 获取表格属性
  const getTableXy = () => {
    tablexy.value = tableDom.value[0].getBoundingClientRect()

    tablexy.value.height = tableDom.value[0].offsetHeight
    return tablexy.value
  }

  const getDom = () => {
    if (!parentDom.value) {
      parentDom.value = document.getElementsByClassName(parent)
    }
  }
  //滚动事件
  const scrollEvent = rafThrottle(async function(e) {
    if (canFixed && parentDom.value[0]) {
      getDom()
      tableDom.value = parentDom.value[0].getElementsByClassName('el-table__header-wrapper')
      if (tablexy.value.top == 0 || !tablexy.value.height || !tablexy.value.top) {
        await getTableXy()
      }
      fixedRightDom.value = parentDom.value[0].getElementsByClassName('el-table__fixed-right')
      fixedLeftDom.value = parentDom.value[0].getElementsByClassName('el-table__fixed')
      paginationDom.value = parentDom.value[0].getElementsByClassName('pagination__wrap')

      let { height, top, left } = tablexy.value
      // let scrollTop = e.target.scrollTop // // 获取距离顶部的距离
      let scrollTop = e.target.scrollTop + 90
      let { fixedRightHeaderDom, fixedRightBox, fixedLeftHeaderDom, fixedLeftBox, dom } = getFixedDom()
      if (scrollTop >= height / 2 + top) {
        // 存在右侧固定表头
        if (fixedRightHeaderDom) {
          setFixedStyle({
            dom: fixedRightHeaderDom,
            left: fixedRightDom.value[0].getBoundingClientRect().left + 'px',
            width: getComputedStyle(fixedRightDom.value[0]).width,
            scrollLeft: fixedRightHeaderDom.scrollWidth
          })
          fixedRightBox.style.top = 0
        }
        // 左侧固定
        if (fixedLeftHeaderDom) {
          setFixedStyle({
            dom: fixedLeftHeaderDom,
            left: left + 'px',
            width: getComputedStyle(fixedLeftDom.value[0]).width,
            scrollLeft: 0
          })
          fixedLeftBox.style.top = 0
        }
        dom.classList.add('fixed') //加一个固定标识
        updateWidth()
        dom.style.position = 'fixed'
        dom.style.zIndex = '2000'
        dom.style.top = 70 + 'px'
        dom.style.overflow = 'hidden'
      } else {
        clearFixedStyle()
      }
    }
  })

  //设置固定
  const setFixedStyle = (data) => {
    let { dom, scrollLeft, width, left } = data
    if (dom) {
      dom.style.zIndex = '2000'
      dom.style.position = 'fixed'
      dom.style.top = '0'
      dom.scrollLeft = scrollLeft
      dom.style.width = width
      dom.style.overflow = 'hidden'
      dom.style.left = left
    }
  }

  // 清空sticky监听事件，页面卸载等情况使用
  const clearFixedStyle = () => {
    if (!tableDom.value) return
    let { height, left } = tablexy.value
    let { dom, fixedRightHeaderDom, fixedRightBox, fixedLeftHeaderDom, fixedLeftBox } = getFixedDom()
    if (dom.classList.contains('fixed')) {
      if (fixedRightHeaderDom) {
        fixedRightBox.style.top = height + 'px'
        fixedRightHeaderDom.removeAttribute('style')
      }
      if (fixedLeftHeaderDom) {
        fixedLeftHeaderDom.style.zIndex = '0'
        fixedLeftHeaderDom.style.position = 'static'
        fixedLeftHeaderDom.style.top = 0 + 'px'
        fixedLeftHeaderDom.style.left = left + 'px'
        fixedLeftBox.style.top = getComputedStyle(dom).height
      }
      dom.classList.remove('fixed')
      dom.style.position = 'static'
      dom.style.top = '0'
      dom.style.zIndex = '0'
    }
  }

  return {
    clearListener,
    setFixedStyle,
    updateFixedRight,
    headerDragend,
    setScrollXWidth,
    clearFixedStyle
  }
}
